﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;


namespace OrderManagement
{
    [Serializable]
    public class Order:IComparable
    {
        public int Ono { get; set; }//订单号
        public string Gname { get; set; }//商品名
        public string Customer { get; set; }//客户

        public double Oamount { get; set; }//订单金额
        public Order()
        {
            this.Ono = 0;
            this.Gname = string.Empty;
            this.Customer = string.Empty;
            this.Oamount = 0;
        }
        public Order(int onos,string gnames,string customers)
        {
            this.Ono = onos;
            this.Gname = gnames;
            this.Customer = customers;
        }
        public List<OrderDetails> orders = new List<OrderDetails>();
        public int CompareTo(object o)
        {
            Order item = o as Order;
            return this.Ono.CompareTo(item.Ono);

        }
        public override bool Equals(object o)
        {
            Order item = o as Order;
            return this.Ono == item.Ono;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        public void theWholePrice()
        {
            double sum = 0;
            foreach(OrderDetails n in this.orders)
            {
                sum += n.getGAmount();
            }
            this.Oamount = sum;
        }
        public override string ToString()//展示订单明细
        {
            return $"订单号：{Ono}\t商品名：{Gname}\t客户名：{Customer}\t总金额：{Oamount}";
        }
        public void AddDetails(int id, string name, int num, double price)
        {
            bool isEqual = false;
            OrderDetails i = new OrderDetails(id, name, num, price);
            foreach (OrderDetails o in this.orders)
            {
                if (i.Equals(o))
                {
                    isEqual = true;
                    Console.WriteLine("订单内编号重复！");
                }
            }
            if (!isEqual)
            {
                this.orders.Add(i);
                Console.WriteLine("添加成功");
            }
        }
        public void ChangeDetails(int sele3_1,int Eoid,string gnamed,int gnumd,double price) 
        {
            try
            {
                int m, n;
                m = Eoid;
                n = sele3_1;
                switch (n)
                {
                    case 1:
                        string gnamed1 = gnamed;
                        this.orders.ForEach(i =>
                        {
                            if (i.OId == m)
                            {
                                i.Goodname = gnamed1;
                            }
                        }
                        );
                        break;
                    case 2:
                        int gnumd1 = gnumd;
                        this.orders.ForEach(i =>
                        {
                            if (i.OId == m)
                            {
                                i.GoodNum = gnumd1;
                            }
                        }
                        );
                        break;
                    case 3:
                        double price1 = price;
                        this.orders.ForEach(i =>
                        {
                            if (i.OId == m)
                            {
                                i.UnitPrice = price1;
                            }
                        }
                        );
                        break;
                }
            }
            catch
            {
                Console.WriteLine("Error!请检查是否输入错误的单内编号/修改选项/不符修改项类型的数据");
            }
        }   
        public void DeleteDatails(int OidTODel)
        {
            try
            {
                int m = OidTODel;
                for(int i = this.orders.Count - 1; i >= 0; i--)
                {
                    if(this.orders[i].OId == m)
                    {
                        this.orders.Remove(this.orders[i]);
                    }
                }
                Console.WriteLine("已删除");
            }
            catch
            {
                Console.WriteLine("Error!是否输入了不存在/错误的单内编号？");
            }
        }
        public void SortDetails()
        {
            Console.WriteLine("输入1/2/3分别按默认单内编号排序/商品数量/商品单价排序");
            int selec1 = Convert.ToInt32(Console.ReadLine());
            switch (selec1)
            {
                case 1:
                    this.orders.Sort();
                    break;
                case 2:
                    List<OrderDetails> sortDetails = this.orders.OrderBy(s => s.GoodNum).ToList<OrderDetails>();
                    this.orders = sortDetails;
                    break;
                case 3:
                    List<OrderDetails> sortDetails2 = this.orders.OrderBy(s => s.UnitPrice).ToList<OrderDetails>();
                    this.orders = sortDetails2;
                    break;
                default:
                    Console.WriteLine("Error!是否输入错误？");
                    break;
            }
        }
       
    }

    [Serializable]
   public class OrderDetails
   {
        private int orderid;
        public int OId
        {
            get
            {
                return orderid;
            }
            set
            {
                orderid = value;
            }
        }
        private string goodname;
        public string Goodname
        {
            get
            {
                return goodname;
            }
            set
            {
                goodname = value;
            }
        }
        private int goodnum;

        public int GoodNum
        {
            get
            {
                return goodnum;

            }
            set
            {
                goodnum = value;
            }
        }
        private double unitprice;//单价
        public double UnitPrice
        {
            get
            {
                return unitprice;
            }
            set
            {
                unitprice = value;
            }

        }
        public OrderDetails()
        {
            this.orderid = 0;
            this.goodname = string.Empty;
            this.goodnum = 0;
            this.unitprice = 0;
        }
        public OrderDetails(int oid,string Gname, int Gnum, double Unitprice)
        {
            this.orderid = oid;
            this.goodname = Gname;
            this.goodnum = Gnum;
            this.unitprice = Unitprice;
        }
        public double getGAmount()
        {
            double Amount = this.goodnum * this.unitprice;
            return Amount;
        }
        public int CompareTo(object o)
        {
            OrderDetails item = o as OrderDetails;
            return this.OId.CompareTo(item.OId);
        }
        public override bool Equals(object o)
        {
            OrderDetails item = o as OrderDetails;
            return this.OId == item.OId;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return $"订单编号：{OId}\t商品名：{Goodname}\t数量：{GoodNum}\t单价：{UnitPrice}";
        }




    }

    [Serializable]
   public class OrderService
    {
        public List<Order> orderData = new List<Order>();
        public OrderService() { }
        public void AddOrder(int sele,int Ono,string GName,string CusName,int Oid,string GName1,int GNum,double price)
        {
            try
            {
                int onos = Ono;
                string gnames = GName;
                string customers = CusName;
                bool equal = false;
                string gname = GName1;
                int oid = Oid;
                int num = GNum;
                double Addprice = price ;
                Order o = new Order(onos, gnames, customers);
                    foreach (Order i in this.orderData)
                    {
                        if (i.Equals(o))
                        {
                            Console.WriteLine("请不要创建订单号重复的订单");
                            equal = true;
                        }
                    }
                if (!equal)
                {       
                    o.AddDetails(oid, gname, num, Addprice);
                    orderData.Add(o);
                    o.theWholePrice();
                    Console.WriteLine("订单添加成功");
                }                                   
            }
            catch
            {
                Console.WriteLine("Error!请检查输入类型是否正确等");
            }
        }
        public void AddOrder(int sele,int Ono,int Oid,string GName1, int GNum, double price)
        {
            try
            {
                int onos1 = Ono;
                string GNamed1 = GName1;
                int oid1 = Oid;
                int num1 = GNum;
                double Addprice1 = price;
                this.orderData.ForEach(i =>
                {
                    if (i.Ono == onos1)
                    {
                        i.AddDetails(oid1, GNamed1, num1, Addprice1);
                        i.theWholePrice();
                        Console.WriteLine("添加成功！");
                    }
                });
               

            }
            catch
            {
                Console.WriteLine("Error!请检查输入类型是否正确等");
            }
        }
        public void DeleteOrder(int DelSel,int OnoToDel,int OidToDel = 0)
        {
            try
            {
                int dono = OnoToDel;
                int doid = OidToDel;
                switch (DelSel)
                {
                    case 1:
                        for(int i = this.orderData.Count - 1; i >= 0; i--)
                        {
                            if(this.orderData[i].Ono == dono)
                            {
                                this.orderData.Remove(this.orderData[i]);
                            }
                        }
                        Console.WriteLine("已删除");
                        break;
                    case 2:
                        for (int i = this.orderData.Count - 1; i >= 0; i--)
                        {
                            if (this.orderData[i].Ono == dono)
                            {
                                this.orderData[i].DeleteDatails(doid);
                            }
                        }
                        break;
                }

            }
            catch
            {
                Console.WriteLine("Error!请检查是否输入错误。");

            }

        }
        public void ChangeOrder(int sele3,int Eono,string Estring)
        {
            try
            {

                int m = Eono;
                int n = sele3;
                switch (n)
                {
                    case 1:
                        string CGname = Estring;
                        this.orderData.ForEach(i =>
                        {
                            if (i.Ono == m)
                            {
                                i.Gname = CGname;
                                Console.WriteLine("修改成功！");
                            }
                        }
                        );
                        break;
                    case 2:
                        string CCname = Estring;
                        this.orderData.ForEach(i =>
                        {
                            if (i.Ono == m)
                            {
                                i.Customer = CCname;
                                Console.WriteLine("修改成功！");
                            }
                        }
                        );
                        break;


                }
            }
            catch
            {
                Console.WriteLine("Error!请检查订单号是否错误/是否输入不存在选项等");
            }
        }
        public void ChangeOrder(int sele3,int Eono,int sele3_1,int Eoid,string gnamed = "",int gnum = 0,double price = 0.00)
        {
            try
            {
                int m, n;
                m = Eono;
                n = sele3;
                switch (n)
                {
                    case 3:
                        this.orderData.ForEach(i =>
                        {
                            if (i.Ono == m)
                            {
                                i.ChangeDetails(sele3_1,Eoid,gnamed,gnum,price);
                                i.theWholePrice();
                                Console.WriteLine("修改成功！");
                            }
                        }
                        );

                        break;


                }
            }
            catch
            {
                Console.WriteLine("Error!请检查订单号是否错误/是否输入不存在选项等");
            }
        }
        public List<Order> searchOrderByLinq(int n,int Eint1,int Eint2=0)
        {
            List<Order> sel = new List<Order>();
            try { 

                switch (n)
                {
                    case 1: 
                        int orderno = Eint1;
                        var query1 = from Sel1 in orderData
                                     where Sel1.Ono == orderno
                                     orderby Sel1.Oamount
                                     select Sel1;
                        sel = query1.ToList();
                        Console.WriteLine("符合条件的订单：");
                        for (int i = 0; i < sel.Count; i++)
                        {
                            Console.WriteLine(sel[i].ToString());
                            for(int m = 0; m < sel[i].orders.Count; m++)
                            {
                                Console.WriteLine(sel[i].orders[m].ToString());
                            }
                        }
                        break;

                    case 4:
                        int MaxOamount = Eint1;
                        int MinOamount = Eint2;
                        var query4_1 = from Sel4 in orderData
                                       where Sel4.Oamount <= MaxOamount
                                       orderby Sel4.Oamount
                                       select Sel4;
                        var query4_2 = from Sel5 in query4_1
                                       where MinOamount <= Sel5.Oamount
                                       orderby Sel5.Oamount
                                       select Sel5;
                        sel = query4_2.ToList();
                        Console.WriteLine("符合条件的订单：");
                        for (int i = 0; i < sel.Count; i++)
                        {
                            Console.WriteLine(sel[i].ToString());
                            for (int m = 0; m < sel[i].orders.Count; m++)
                            {
                                Console.WriteLine(sel[i].orders[m].ToString());
                            }
                        }
                        break;



                }
            }
            catch
            {
                Console.WriteLine("Error!请检查是否输入错误数据");
            }
            return sel;

        }
        public List<Order> searchOrderByLinq(int n,string Estring)
        {
            List<Order> sel = new List<Order>();
            try
            {

                switch (n)
                {

                    case 2:
                        string gName = Estring;
                        var query2 = from Sel2 in orderData
                                     where Sel2.Gname == gName
                                     orderby Sel2.Oamount
                                     select Sel2;
                        sel = query2.ToList();
                        Console.WriteLine("符合条件的订单：");
                        for (int i = 0; i < sel.Count; i++)
                        {
                            Console.WriteLine(sel[i].ToString());
                            for (int m = 0; m < sel[i].orders.Count; m++)
                            {
                                Console.WriteLine(sel[i].orders[m].ToString());
                            }
                        }
                        break;
                    case 3:
                        string custoname = Estring;
                        var query3 = from Sel3 in orderData
                                     where Sel3.Customer == custoname
                                     orderby Sel3.Oamount
                                     select Sel3;
                        sel = query3.ToList();
                        Console.WriteLine("符合条件的订单：");
                        for (int i = 0; i < sel.Count; i++)
                        {
                            Console.WriteLine(sel[i].ToString());
                            for (int m = 0; m < sel[i].orders.Count; m++)
                            {
                                Console.WriteLine(sel[i].orders[m].ToString());
                            }
                        }
                        break;
                }
            }

            catch
            {
                Console.WriteLine("Error!请检查是否输入错误数据");
            }
            return sel;
        }
        public void export()
        {
            XmlSerializer toXml = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream("OrderXml.xml", FileMode.Create))
            {
                toXml.Serialize(fs, this.orderData);
            }
            Console.WriteLine("已序列化为xml格式");
            Console.WriteLine(File.ReadAllText("OrderXml.xml"));
        }
        public List<Order> import()
        {
            List<Order> OD = new List<Order>();
            XmlSerializer toDeXml = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream("OrderXml.xml", FileMode.Open))
            {
                OD = (List<Order>)toDeXml.Deserialize(fs);
                Console.WriteLine("从OrderXml.xml反序列化结果：");
                for (int i = 0; i <OD.Count; i++)
                {
                    Console.WriteLine(OD[i].ToString());
                    for (int m = 0; m < OD[i].orders.Count; m++)
                    {
                        Console.WriteLine(OD[i].orders[m].ToString());
                    }
                }
            }
            return OD;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            OrderService service = new OrderService();
            bool run = true;


            while (run)
            {
                Console.WriteLine("增：输入‘增’ 删：输入‘删’ 改：输入‘改’ 查：输入‘查’ 排序：输入‘排序’ 输出：输入‘输出’显示订单信息 序列化：输入“序列化”序列化订单信息为xml格式 反序列化：输入“反序列化”由xml文件反序列化生成订单信息 退出：输入‘退出’");
                string sel = Console.ReadLine();
                switch (sel)
                {
                    case "增":
                        Console.WriteLine("输入1新建一个有一条明细新订单，输入2在已有订单项中新增一条明细");
                        int selen;
                        selen = Convert.ToInt32(Console.ReadLine());
                        switch (selen)
                        {
                            case 1:
                                Console.WriteLine("输入订单号：");
                                int onos = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("输入订单中所有商品名：");
                                string gnames = Console.ReadLine();
                                Console.WriteLine("输入下单客户名：");
                                string customers = Console.ReadLine();
                                Console.WriteLine("输入明细单内编号：");
                                int oidn = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("输入商品名：");
                                string gnames1 = Console.ReadLine();
                                Console.WriteLine("输入商品数量：");
                                int gnumn = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("输入商品单价：");
                                double pricens = Convert.ToDouble(Console.ReadLine());
                                service.AddOrder(selen, onos, gnames, customers, oidn, gnames1, gnumn, pricens);
                                break;
                            case 2:
                                Console.WriteLine("输入要添加明细订单号：");
                                int onoToAdd = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("输入明细单内编号：");
                                int AddOid = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("输入商品名：");
                                string AddGName = Console.ReadLine();
                                Console.WriteLine("输入商品数量");
                                int AddNum = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("输入商品单价：");
                                double AddPrice = Convert.ToDouble(Console.ReadLine());
                                service.AddOrder(selen, onoToAdd, AddOid, AddGName, AddNum, AddPrice);
                                break;
                        }
                        break;
                    case "删":
                        Console.WriteLine("输入1删除订单项，输入2删除订单项中某项明细");
                        int SelDel = Convert.ToInt32(Console.ReadLine());
                        switch (SelDel)
                        {
                            case 1:
                                Console.WriteLine("请输入要删除订单的订单号：");
                                int DelOno = Convert.ToInt32(Console.ReadLine());
                                service.DeleteOrder(SelDel, DelOno);
                                break;
                            case 2:
                                Console.WriteLine("请输入要删除明细的订单的订单号：");
                                int DelOno1 = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("请输入要删除的明细的单内编号：");
                                int DelOid = Convert.ToInt32(Console.ReadLine());
                                service.DeleteOrder(SelDel, DelOno1, DelOid);
                                break;
                        }
                        break;
                    case "改":
                        Console.WriteLine("输入要修改项的订单号：");
                        int COno = Convert.ToInt32(Console.ReadLine());
                        Console.WriteLine("输入1/2/3分别改动订单项的商品名/客户名/某条明细项");
                        int sele3 = Convert.ToInt32(Console.ReadLine());
                        switch (sele3)
                        {
                            case 1:
                                Console.WriteLine("输入要改为的商品名：");
                                string goodName = Console.ReadLine();
                                service.ChangeOrder(sele3, COno, goodName);
                                break;
                            case 2:
                                Console.WriteLine("输入要改为的客户名");
                                string cusName = Console.ReadLine();
                                service.ChangeOrder(sele3, COno, cusName);
                                break;
                            case 3:
                                Console.WriteLine("输入明细单内编号：");
                                int COid = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("输入1/2/3分别可修改明细中商品名/商品数量/商品单价");
                                int sele3_1 = Convert.ToInt32(Console.ReadLine());
                                switch (sele3_1)
                                {
                                    case 1:
                                        Console.WriteLine("输入要修改为的商品名：");
                                        string gNamen = Console.ReadLine();
                                        service.ChangeOrder(sele3, COno, sele3_1, COid, gNamen);
                                        break;
                                    case 2:
                                        Console.WriteLine("输入要改为的商品数量：");
                                        int gNumn = Convert.ToInt32(Console.ReadLine());
                                        service.ChangeOrder(sele3, COno, sele3_1, COid,gnum:gNumn);
                                        break;
                                    case 3:
                                        Console.WriteLine("输入要改为的价格：");
                                        double pricen = Convert.ToDouble(Console.ReadLine());
                                        service.ChangeOrder(sele3, COno, sele3_1, COid, price: pricen);
                                        break;

                                }
                                break;
                        }
                        break;
                    case "查":
                        Console.WriteLine("输入1/2/3/4可分别按订单号/商品名/客户名/总金额查询订单。");
                        int sele1 = Convert.ToInt32(Console.ReadLine());
                        List<Order> searchResult = new List<Order>();
                        switch (sele1)
                        {
                            case 1:
                                Console.WriteLine("请输入订单号：");
                                int Eoid = Convert.ToInt32(Console.ReadLine());
                                searchResult = service.searchOrderByLinq(sele1, Eoid);
                                break;
                            case 2:
                                Console.WriteLine("请输入商品名：");
                                string EgName = Console.ReadLine();
                                searchResult = service.searchOrderByLinq(sele1, EgName);
                                break;
                            case 3:
                                Console.WriteLine("请输入客户名：");
                                string ECName = Console.ReadLine();
                                searchResult = service.searchOrderByLinq(sele1, ECName);
                                break;
                            case 4:
                                Console.WriteLine("请输入总金额上限：");
                                int EMaxO = Convert.ToInt32(Console.ReadLine());
                                Console.WriteLine("请输入总金额下限：");
                                int EMinO = Convert.ToInt32(Console.ReadLine());
                                searchResult = service.searchOrderByLinq(sele1, EMaxO, EMinO);
                                break;
                        }
                        break;
                    case "排序":
                        Console.WriteLine("输入1/2/3可分别:默认按订单号排序/按订单金额排序/对订单中订单明细进行排序");
                        int sele2 = Convert.ToInt32(Console.ReadLine());
                        switch (sele2) {
                            case 1:
                                service.orderData.Sort();
                                break;
                            case 2:
                                List<Order> sortOrder = service.orderData.OrderBy(s => s.Oamount).ToList<Order>();
                                service.orderData = sortOrder;
                                break;
                            case 3:
                                Console.WriteLine("请输入要对明细排序的订单号");
                                int sono = Convert.ToInt32(Console.ReadLine());
                                service.orderData.ForEach(i =>
                                {
                                    if (i.Ono == sono)
                                    {
                                        i.SortDetails();
                                    }
                                }
                                );
                                break;
                            default:
                                Console.WriteLine("Error!是否输入错误？");
                                break;
                        }
                
                        break;
                    case "输出":
                        for (int i = 0; i < service.orderData.Count; i++)
                        {
                            Console.WriteLine(service.orderData[i].ToString());
                            for (int m = 0; m < service.orderData[i].orders.Count; m++)
                            {
                                Console.WriteLine(service.orderData[i].orders[m].ToString());
                            }
                        }
                        break;
                    case "序列化":
                        service.export();
                        break;
                    case "反序列化":
                        List<Order> searchResult2 = new List<Order>();
                        searchResult2 = service.import();
                        break;
                    case "退出":
                        run = false;
                        break;
                    default:
                        Console.WriteLine("Error!请检查是否输入错误！");
                        break;
                }
            }
        }
    }
}
